home *** CD-ROM | disk | FTP | other *** search
- obfs2 (The Twobfuscator)
-
- 0. Protocol overview
-
- This is a protocol obfuscation layer for TCP protocols. Its purpose
- is to keep a third party from telling what protocol is in use based
- on message contents. It is based on brl's ssh obfuscation protocol.
-
- It does not provide authentication or data integrity. It does not
- hide data lengths. It is more suitable for providing a layer of
- obfuscation for an existing authenticated protocol, like SSH or TLS.
-
- The protocol has two phases: in the first phase, the parties
- establish keys. In the second, the parties exchange superenciphered
- traffic.
-
- 1. Primitives, notation, and constants.
-
- H(x) is SHA256 of x.
- H^n(x) is H(x) called iteratively n times.
-
- E(K,s) is the AES-CTR-128 encryption of s using K as key.
-
- x | y is the concatenation of x and y.
- UINT32(n) is the 4 byte value of n in big-endian (network) order.
- SR(n) is n bytes of strong random data.
- WR(n) is n bytes of weaker random data.
- "xyz" is the ASCII characters 'x', 'y', and 'z', not NUL-terminated.
- s[:n] is the first n bytes of s.
- s[n:] is the last n bytes of s.
-
- MAGIC_VALUE is 0x2BF5CA7E
- SEED_LENGTH is 16
- MAX_PADDING is 8192
- HASH_ITERATIONS is 100000
-
- KEYLEN is the length of the key used by E(K,s) -- that is, 16.
- IVLEN is the length of the IV used by E(K,s) -- that is, 16.
-
- HASHLEN is the length of the output of H() -- that is, 32.
-
- MAC(s, x) = H(s | x | s)
-
- A "byte" is an 8-bit octet.
-
- We require that HASHLEN >= KEYLEN + IVLEN
-
- 2. Key establishment phase.
-
- The party who opens the connection is the 'initiator'; the one who
- accepts it is the 'responder'. Each begins by generating a seed
- and a padding key as follows. The initiator generates:
-
- INIT_SEED = SR(SEED_LENGTH)
- INIT_PAD_KEY = MAC("Initiator obfuscation padding", INIT_SEED)[:KEYLEN]
-
- And the responder generates:
-
- RESP_SEED = SR(SEED_LENGTH)
- RESP_PAD_KEY = MAC("Responder obfuscation padding", INIT_SEED)[:KEYLEN]
-
- Each then generates a random number PADLEN in range from 0 through
- MAX_PADDING (inclusive).
-
- The initiator then sends:
-
- INIT_SEED | E(INIT_PAD_KEY, UINT32(MAGIC_VALUE) | UINT32(PADLEN) | WR(PADLEN))
-
- and the responder sends:
-
- RESP_SEED | E(RESP_PAD_KEY, UINT32(MAGIC_VALUE) | UINT32(PADLEN) | WR(PADLEN))
-
- Upon receiving the SEED from the other party, each party derives
- the other party's padding key value as above, and decrypts the next
- 8 bytes of the key establishment message. If the MAGIC_VALUE does
- not match, or the PADLEN value is greater than MAX_PADDING, the
- party receiving it should close the connection immediately.
- Otherwise, it should read the remaining PADLEN bytes of padding data
- and discard them.
-
- Additional keys are then derived as:
-
- INIT_SECRET = MAC("Initiator obfuscated data", INIT_SEED|RESP_SEED)
- RESP_SECRET = MAC("Responder obfuscated data", INIT_SEED|RESP_SEED)
- INIT_KEY = INIT_SECRET[:KEYLEN]
- INIT_IV = INIT_SECRET[KEYLEN:]
- RESP_KEY = RESP_SECRET[:KEYLEN]
- RESP_IV = RESP_SECRET[KEYLEN:]
-
- The INIT_KEY value keys a stream cipher used to encrypt values from
- initiator to responder thereafter. The stream cipher's IV is
- INIT_IV. The RESP_KEY value keys a stream cipher used to encrypt
- values from responder to initiator thereafter. That stream cipher's
- IV is RESP_IV.
-
- 3. Shared-secret extension
-
- Optionally, if the client and server share a secret value SECRET,
- they can replace the MAC function with:
-
- MAC(s,x) = H^n(s | x | H(SECRET) | s)
-
- where n = HASH_ITERATIONS.
-